﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Net;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using HtmlAgilityPack;

namespace TravianLib
{
    public class HTTPFetch
    {
        private CookieContainer cookies;
        //private HttpWebRequest req;
        //private HttpWebResponse resp;
        private string _server;
        private string _username;
        private string _password;
        private bool _tryingToLogin = false;

        public HTTPFetch(string username, string password, string server)
        {
            _server = server;
            _username = username;
            _password = password;            
            cookies = new System.Net.CookieContainer();
        }
        public HTTPFetch(string username, string password, string server, CookieCollection cookiess)
        {
            _server = server;
            _username = username;
            _password = password;
            cookies = new System.Net.CookieContainer();            
            foreach (Cookie cookie in cookiess)
            {
                cookie.Domain = _server;
                cookies.Add(cookie);
            }            
        }

        public bool login()
        {
            _tryingToLogin = true;
            string login = "";
            string output = createHTTPrequest("http://" + _server + "/login.php","");
            Regex rgx = new Regex("name=\"([a-zA-Z0-9]*)\".*value=\"([a-zA-Z0-9*]*)\".*(maxlength=\"([0-9]+)\")");
            login = "";
            foreach (Match tmp in rgx.Matches(output))
            {
                login += tmp.Groups[1].Value + "=" + (tmp.Groups[4].Value == "15" ? _username : _password) + "&";
            }
            rgx = new Regex("name=\"([a-zA-Z0-9]*)\".*value=\"([a-zA-Z0-9]*)\" />");
            foreach (Match tmp in rgx.Matches(output))
            {
                login += tmp.Groups[1].Value + "=" + tmp.Groups[2].Value + "&";
            }
            //createHTTPrequest("http://" + server + "/dorf1.php", "w=1280%3A800&login=1239637588&ee2510f=" + username + "&e3641b2=" + password + "&e7c8fff=&s1.x=34&s1.y=13&s1=login");
            output = createHTTPrequest("http://" + _server + "/dorf1.php", login.Remove(login.Length - 1));
            if (output.Contains("href=\"login.php\""))
            {
                _tryingToLogin = false;
                return false;
            }
            else
            {
                _tryingToLogin = false;
                return true;
            }
        }

        public string createHTTPrequest(string url)
        {
            return createHTTPrequest(url, "");
        }
        public string createHTTPrequest(string url, string post)
        {
            try
            {
                if (!url.StartsWith("http://")) {
                    url = "http://" + _server + url;   
                }
                string output = "";
                HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(new Uri(url));                
                req.CookieContainer = cookies;
                req.Proxy = null;
                //req.Proxy = new System.Net.WebProxy(ProxyString, true);
                req.ContentType = "application/x-www-form-urlencoded";
                if (post.Length != 0)
                {
                    req.Method = "POST";
                    byte[] bytes = System.Text.Encoding.UTF8.GetBytes(post);
                    req.ContentLength = bytes.Length;
                    req.Timeout = 20000;

                    System.IO.Stream os = req.GetRequestStream();
                    os.Write(bytes, 0, bytes.Length);
                    os.Close();
                }
                else
                {
                    req.Method = "GET";
                }
                req.UserAgent = "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-GB; rv:1.9.0.8) Gecko/2009032609 Firefox/3.0.8 (.NET CLR 3.5.30729)";

                HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
                Encoding encode;
                if (resp.CharacterSet == null)
                {
                    encode = System.Text.Encoding.GetEncoding("ASCII");
                }
                else
                {
                    encode = System.Text.Encoding.GetEncoding(resp.CharacterSet);
                }
                System.IO.StreamReader sr = new System.IO.StreamReader(resp.GetResponseStream(), encode);
                output = cleanTDs(sr.ReadToEnd());
               
                if (output.Contains("href=\"login.php\"") && !_tryingToLogin)
                {
                    NewHttpRequest(req);
                    login();
                    return createHTTPrequest(url, post);
                    //return "-1";
                }
                else
                {
                    NewHttpRequest(req);
                }
                if (!url.Contains("berichte.php"))
                {
                    parseTravian(output);
                }
                else if (resp.ResponseUri.AbsoluteUri.Contains("build.php?gid=16"))
                {
                    HtmlAgilityPack.HtmlDocument doc = new HtmlDocument();
                    doc.LoadHtml(output);

                    foreach (HtmlNode table in doc.DocumentNode.SelectNodes("//table[@class='troop_details']"))
                    {
                        foreach (HtmlNode tdRole in table.SelectNodes("//td[@class='role']")) 
                        {
                            if (tdRole.InnerText != "KYLA")
                            {
                                    //HYOKKAYS!!
                            }
                        }
                    }
                }
                return output;
            }
            catch (Exception ex)
            {
                System.Windows.Forms.MessageBox.Show(ex.ToString());
                return "";
               // return this.createHTTPrequest(url, post);
            }
        }
        
        private string cleanTDs(string contents)
        {
            StringBuilder output = new StringBuilder();
            bool cut = false;
            string[] lines = contents.Split("\r\n".ToCharArray());
            foreach (string tmp in lines)
            {
                if (tmp.Contains("<td"))
                {
                    cut = true;
                }
                if (tmp.Contains("</td>"))
                {
                    cut = false;
                }
                if (cut)
                {
                    output.Append(tmp.Trim());
                }
                else
                {
                    output.Append(tmp + "\n");
                }

            }
            return output.ToString();
        }
        private void parseTravian(string contents)
        {
            Regex rgx = new Regex("l[1-4].*title=([\"a-zA-Z0-9 ]+).*>[&nbsp;]*([0-9]+)/([0-9]+)");
            MatchCollection resources = rgx.Matches(contents);
            if (ResourcesUpdated != null && resources.Count > 0)
            {
                TravianLib.resources resources_ = new TravianLib.resources();
                resources_.changed = DateTime.Now;
                resources_.wood = int.Parse(resources[0].Groups[2].Value);
                resources_.clay = int.Parse(resources[1].Groups[2].Value);
                resources_.iron = int.Parse(resources[2].Groups[2].Value);
                resources_.crop = int.Parse(resources[3].Groups[2].Value);
                ResourcesUpdated(resources_);
            }
            if (NewReport != null && contents.Contains("<div id=\"n5\" class=\"i3\">"))
            {
                NewReport(this,new EventArgs());
            }
        }
        public event EventHandler NewReport;
        public event ResourcesUpdatedHandler ResourcesUpdated;
        public event HttpRequestEventHandler NewHttpRequest;
        public delegate void ResourcesUpdatedHandler(TravianLib.resources resources);
        public delegate void HttpRequestEventHandler(HttpWebRequest wr);

        public void WriteXml()
        {
            System.IO.File.Delete(_username + ".conf");
            System.Data.DataSet ds = new System.Data.DataSet();
            System.Data.DataTable dt = new System.Data.DataTable();
            dt.TableName = "settings";
            dt.Columns.Add("setting", typeof(string));
            dt.Columns.Add("value", typeof(string));
            foreach (Cookie tmp in cookies.GetCookies(new Uri("http://" + _server)))
            {
                dt.Rows.Add(new object[] { tmp.Name, tmp.Value });
            }
            dt.Rows.Add(new object[] { "username", _username });
            dt.Rows.Add(new object[] { "password", _password });
            dt.Rows.Add(new object[] { "server", _server });

            dt.WriteXml(_username + ".conf");
        }
    }
}
